/*
 * @(#)HillClimbing.java 1.50 09/11/13
 * 
 * Clase Compartida
 * PROP Grupo 13 Cluster 3
 */

/**
 * Implementaci�n del algoritmo de optimizaci�n HillClimbing a partir de un camino optimizado generado por la clase que implemente el algoritmo de Christophides.
 * Si se encuentra un camino m�s optimo, se retorna. De lo contrario se trabajar� con el inicial, aportado por el otro algoritmo.
 * 
 * @author Anna L�pez Mora
 */
package dominio;

import java.util.ArrayList;

public class HillClimbing {
	
	Graph grafo_copia;
	ArrayList<Nodes> nodelist, copia, copia_original;
	int coste_mejora, coste_original; 
	int operadores = 3; //numero de operadores pensados para realizar una optimizaci�n sobre los datos.
	int salir = 0;
	
	public HillClimbing(Graph grafo_original) {
		grafo_copia = grafo_original;
		nodelist = grafo_copia.list;
		coste_original = contar(nodelist);
		copia_original = nodelist;
		copia_original.remove(0);
		copia_original.remove(copia_original.size()-1);
		
	}
	
	
	public Graph ordenacion() {
		
		while(operadores > 0 && salir == 0){
			copia = copia_original;
			operador(operadores, copia);
			copia.add(0, nodelist.get(0));
			copia.add(nodelist.get(nodelist.size()-1));
			coste_mejora = contar(copia);
			if(coste_mejora < coste_original) {
				grafo_copia.cost = coste_mejora;
				grafo_copia.list = copia;
			}
			--operadores;
		}
		return grafo_copia;
		
	}
	public void operador(int op, ArrayList<Nodes> copia){
		ArrayList<Nodes> aux = copia;
		if(op == 1) {
			for(int i = 0; i < copia.size(); i += 2)  {
				if(i < copia.size()-1) {
					aux.remove(i);
					aux.remove(i+1);
					aux.add(i, copia.get(i+1));
					aux.add(i+1, copia.get(i));
					copia = aux;
				}
			}
		}
		else if(op == 2) {
			aux.remove(0);
			aux.remove(copia.size()-1);
			aux.add(0, copia.get(copia.size()-1));
			aux.add(copia.get(0));
		}
		else if(op == 3) {
			aux.clear();
			for(int i = copia.size()-1; i >= 0; --i) {
				aux.add(copia.get(i));
			}
		}
	}
	
	public int contar(ArrayList<Nodes> copia){
		int coste = 0;
		for(int i = 0; i < copia.size();++i) {
			if(i < copia.size()-1) {
				coste += Busca_siguiente(copia.get(i), copia.get(i+1).id);
			}
			else {
				//a�adir coste personal, si lo tiene
			}
		}
		return coste;
	}
	
	public int Busca_siguiente(Nodes ni, int id) {
		int coste = 0;
		coste += ni.costs.get(id).cost;
		return coste;
	}
	

}

